package com.zbec.mdrs.license.security;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Crypto {
	protected static Logger logger = LoggerFactory.getLogger(Crypto.class);

	public static String encrypt(String text, String key) {
		if (logger.isDebugEnabled()) {
			logger.debug((new StringBuilder())
					.append("Before encrypt text is : ").append(text)
					.toString());
			logger.debug((new StringBuilder()).append("encrytp key is : ")
					.append(key).toString());
		}
		if (StringUtils.isEmpty(key))
			return text;
		byte arrB[] = text.getBytes();
		byte keyB[] = key.getBytes();
		byte realKeyB[] = new byte[keyB.length / 2];
		int i = 0;
		for (int j = 0; j < realKeyB.length; j++) {
			realKeyB[j] = keyB[i];
			i += 2;
		}

		realKeyB = circumvolve(realKeyB);
		byte returnB[] = new byte[arrB.length];
		for (i = 0; i < arrB.length;) {
			int j = 0;
			while (j < realKeyB.length && i < arrB.length) {
				returnB[i] = (byte) (arrB[i] ^ realKeyB[j]);
				i++;
				j++;
			}
		}

		returnB = circumvolve(returnB);
		String returnStr = Base64.encodeBase64URLSafeString(returnB);
		if (logger.isDebugEnabled())
			logger.debug((new StringBuilder()).append("encypt text is : ")
					.append(returnStr).toString());
		return returnStr;
	}

	public static String decrypt(String crpherText, String key) {
		if (logger.isDebugEnabled()) {
			logger.debug((new StringBuilder())
					.append("Before decrypt text is : ").append(crpherText)
					.toString());
			logger.debug((new StringBuilder()).append("decrypt key is : ")
					.append(key).toString());
		}
		if (StringUtils.isEmpty(crpherText))
			return crpherText;
		if (StringUtils.isEmpty(key))
			return crpherText;
		byte arrB[] = Base64.decodeBase64(crpherText.getBytes());
		arrB = circumvolve(arrB);
		byte keyB[] = key.getBytes();
		byte realKeyB[] = new byte[keyB.length / 2];
		int i = 0;
		for (int j = 0; j < realKeyB.length; j++) {
			realKeyB[j] = keyB[i];
			i += 2;
		}

		realKeyB = circumvolve(realKeyB);
		byte returnB[] = new byte[arrB.length];
		for (i = 0; i < arrB.length;) {
			int j = 0;
			while (j < realKeyB.length && i < arrB.length) {
				returnB[i] = (byte) (arrB[i] ^ realKeyB[j]);
				i++;
				j++;
			}
		}

		if (logger.isDebugEnabled())
			logger.debug((new StringBuilder()).append("Decrypt text is : ")
					.append(new String(returnB)).toString());
		return new String(returnB);
	}

	private static byte[] circumvolve(byte arrB[]) {
		byte returnB[] = new byte[arrB.length];
		for (int i = 0; i < arrB.length; i++) {
			int src = arrB[i];
			int lmove = src << 4 & 240;
			int rmove = src >> 4 & 15;
			returnB[i] = (byte) (lmove + rmove);
		}

		return returnB;
	}

	public static void main(String[] args) {
		System.out.println(Crypto.encrypt("xxxxxxxxxxx", "asdfasdf"));
		System.out.println(Crypto.decrypt("5uPm4-bj5uPm4-Y", "asdfasdf"));
	}
}
